#include "EndoscopeRenderWidget.h"
#include <vtkKWTkUtilities.h>
#include <vtkobject.h>
#include <vtkobjectfactory.h>
#include <vtkRenderer.h>
#include <vtkPointData.h>
#include <vtkActor2D.h>
#include <vtkImageMapper.h>
#include <vtkImageData.h>
#include <memory.h>
#include "EndoscopeLogic.h"
#include <vtkUnsignedCharArray.h>
#include "IFImg.h"
#include <time.h>
vtkStandardNewMacro(vtkEndoscopeRenderWidget);
vtkCxxRevisionMacro(vtkEndoscopeRenderWidget, "$Revision: 1.0 $");

void vtkEndoscopeRenderWidget::Animation()
{
	IMGCAPSTATUS status;
	ImgGetCaptureStatus(ESLogic->GetImageCardHandle(), &status);
	clock_t tBegin = clock();	
	while ((status.dwCapture) & 0x01 != 0)
	{
		clock_t tEnd =  clock();
		if (tEnd - tBegin > 100)
			break;
		ImgGetCaptureStatus(ESLogic->GetImageCardHandle(), &status);
	}
	char * p = ESLogic->GetBuffer();
	unsigned char * pixel = Pixels->GetPointer(0);
	for (int j = 0; j < 480; ++j)
	{
		if (j % 2 == 0)
		{
			memcpy(pixel + (479 - j) * 640 * 3, p + j / 2 * 640 * 3, 640 * 3);
		}
		else
		{
			memcpy(pixel + (479 - j) * 640 * 3, p + (j / 2 + 240) * 640 * 3, 640 * 3);
		}
	}
	// begin to capture next frame;
	ImgStartCapture(ESLogic->GetImageCardHandle(), 1, IFIMG_DMACAPTURE_START);
	// handle the captured image
	memcpy(ESLogic->GetCvImage()->imageData, pixel, 640 * 480 * 3);
	// exchange R and B components
	for (int i = 0; i < 640; ++i)
		for (int j = 0; j < 480; ++j)
		{
			unsigned char t;
			t = pixel[j * 640 * 3 + 3 * i + 0];
			pixel[j * 640 * 3 + 3 * i + 0] = pixel[j * 640 * 3 + 3 * i + 2];
			pixel[j * 640 * 3 + 3 * i + 2] = t;
		}
	// here are some opencv handling
	



   //////////////////////////////////////////////////////////////////////////
	cvShowImage("Endoscope Image", ESLogic->GetCvImage());
	
	ImageData->Modified();
	Render();
	if (IsAnimation)
	{
		vtkKWTkUtilities::CreateTimerHandler(GetApplication(), 50, this, "Animation");
		
	}
}
vtkEndoscopeRenderWidget::vtkEndoscopeRenderWidget(void)
{
	ImageMapper = NULL;
	Actor2D = NULL;
	ImageData = NULL;
	Pixels = NULL;
	ESLogic = NULL;
	IsAnimation = false;
}

vtkEndoscopeRenderWidget::~vtkEndoscopeRenderWidget(void)
{
	if (ImageMapper != NULL)
		ImageMapper->Delete();
	if (Actor2D != NULL)
		Actor2D->Delete();
	if (ImageData != NULL)
		ImageData->Delete();
	if (Pixels != NULL)
		Pixels->Delete();

	SetESLogic(NULL);
}

void vtkEndoscopeRenderWidget::InitialPipeline(void)
{
	ImageData = vtkImageData::New();
	ImageData->SetDimensions(640, 480, 1);
	ImageData->SetSpacing(1, 1, 1);
	vtkPointData * pointData = ImageData->GetPointData();
	Pixels = vtkUnsignedCharArray::New();
	Pixels->SetNumberOfComponents(3);
	unsigned char pixel[3];
	for (int i = 0; i < 640; ++i)
		for (int j = 0; j < 480; ++j)
		{
			pixel[0] = 255; pixel[1] = 255; pixel[2] = 255;
			Pixels->InsertNextTupleValue(pixel);
		}
	pointData->SetScalars(Pixels);
	ImageMapper = vtkImageMapper::New();
	ImageMapper->SetInput(ImageData);
	ImageMapper->SetColorWindow(255);
	ImageMapper->SetColorLevel(127.5);
	Actor2D = vtkActor2D::New();
	Actor2D->SetMapper(ImageMapper);
	GetRenderer()->AddActor2D(Actor2D);
}
